﻿// -----------------------------------------------------------------------
// <copyright file="MessageProcessorService.cs" company="">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace TPTecnicas.MessageProcessor.Services
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml.Linq;
    using System.Configuration;
    using TPTecnicas.MessageProcessor.Services.Interfaces;
    using TPTecnicas.MessageProcessor.Common;
    using TPTecnicas.MessageProcessor.Services.EmailSenderService;
    using TPTecnicas.MessageProcessor.Persistence;
    using TPTecnicas.MessageProcessor.Business;
    using System.ComponentModel.Composition;
    using System.ComponentModel.Composition.Hosting;
    using System.ComponentModel.Composition.Primitives;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class MessageProcessorService : IMessageProcessorService
    {
        private readonly EmailSenderClient _emailSenderClient;
        private readonly IDictionary<string, IRule> _rules;
        private readonly IDictionary<string, IAction> _actions;
        private readonly IUniversityContext _context;
        private readonly XDocument _rules2Actions;
        private readonly PluginsRepository _pluginsRepository;

        public MessageProcessorService()
        {
            _emailSenderClient = new EmailSenderClient();
            _context = new InMemoryContext();
            _rules2Actions = XDocument.Load(ConfigurationManager.AppSettings["Rules2ActionsPath"]);
            _pluginsRepository = new PluginsRepository(_context);
            _rules = _pluginsRepository.GetRules(_rules2Actions.Descendants("rule").Select(r => r.Attribute("name").Value));
            _actions = _pluginsRepository.GetActions(_rules2Actions.Descendants("action").Select(r => r.Attribute("name").Value).Distinct());
            SubscribeActions();
        }

        private void SubscribeActions()
        {
            foreach (var rule in _rules2Actions.Descendants("rule"))
            {
                foreach (var action in rule.Descendants("action"))
                {
                    _rules[rule.Attribute("name").Value].Attach(_actions[action.Attribute("name").Value]);
                }
            }
        }

        public void ProcessMessage(Message message)
        {
            foreach (var rule in _rules.Values)
            {
                try
                {
                    rule.ApplyTo(message);
                }
                catch (Exception ex)
                {
                    //TODO
                }
            }

            foreach (var messageToSend in _context.MessagesToSend)
            {
                _emailSenderClient.SendMail(messageToSend);
            }

            _context.MessagesToSend.Clear();

            _context.SaveChanges();

        }
    }
}
